package org.flown.novel.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.flown.novel.data.Author;
import org.flown.novel.data.Book;
import org.flown.novel.data.Chapter;
import org.flown.novel.service.BookService;
import org.flown.novel.service.ServiceResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.stream.FileImageInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

@RequestMapping("/book")
@Controller
public class BookController
{
    @Autowired
    private BookService service_book;


    /*Book*/

    @ResponseBody
    @RequestMapping("/getBookByID")
    public Book getBookByID(@RequestParam(value = "id") int book_id) {return this.service_book.getBookByID(book_id);}

    @ResponseBody
    @RequestMapping("/getBookByName")
    public Book getBookByName(@RequestParam("name") String name)
    {
        return this.service_book.getBookByName(name);
    }



    private byte[] getImageBytes(String path)
            throws IOException
    {
        FileImageInputStream image_stream = new FileImageInputStream(new File(path));
        byte[] image = new byte[(int) image_stream.length()];
        image_stream.readFully(image);
        return image;
    }


    @RequestMapping(value = "/getBookCoverByID")
    public void getBookCoverByID(HttpServletResponse response, @RequestParam("id") int book_id)
            throws IOException
    {
        Book book = this.getBookByID(book_id);
        if (book == null)
            return;
        String path = book.getCoverRealPath();

        if (path.contains(".jpg") || path.contains(".jpeg"))
            response.setContentType(MediaType.IMAGE_JPEG_VALUE);
        else if(path.contains(".png"))
            response.setContentType(MediaType.IMAGE_PNG_VALUE);
        else if(path.contains(".gif"))
            response.setContentType(MediaType.IMAGE_GIF_VALUE);

        OutputStream out = response.getOutputStream();
        out.write(this.getImageBytes(path));
        out.close();
    }

    @ResponseBody
    @RequestMapping(value = "/getBookCoverByName")
    public void getBookCoverByName(HttpServletResponse response, @RequestParam("name") String name)
            throws IOException
    {
        Book book = this.getBookByName(name);
        if (book == null)
            return;
        String path = book.getCoverRealPath();

        if (path.contains(".jpg") || path.contains(".jpeg"))
            response.setContentType(MediaType.IMAGE_JPEG_VALUE);
        else if(path.contains(".png"))
            response.setContentType(MediaType.IMAGE_PNG_VALUE);
        else if(path.contains(".gif"))
            response.setContentType(MediaType.IMAGE_GIF_VALUE);

        OutputStream out = response.getOutputStream();
        out.write(this.getImageBytes(path));
        out.close();
    }


    @ResponseBody
    @RequestMapping(value = "/getBookDirectoryByID", produces = MediaType.APPLICATION_JSON_VALUE)
    public String getBookDirectoryByID(@RequestParam(value = "id") int book_id)
            throws JsonProcessingException
    {
        return this.service_book.getBookDirectory(book_id);
    }


    /**
     * 须得登录了作者后台才行
     * */
    @ResponseBody
    @PostMapping("/publishBook")
    public String publishBook(HttpSession session, @RequestParam String name, String synopsis)
    {
        Author author = (Author)session.getAttribute(SessionAttribute.AUTHOR.getName());
        if (author == null)
            return "作者未登录";

        ServiceResult result = this.service_book.publishBook(author, name, synopsis);
        return switch (result)
        {
            case SUCCESS -> {
                //发书后author会被修改
                session.setAttribute(SessionAttribute.AUTHOR.getName(), author);
                yield "发布成功";
            }
            case EXISTS_NAME -> "书名已被使用";
            case NULL_NAME -> "书名为空";
            default -> "发布失败";
        };
    }

    @ResponseBody
    @PostMapping("/deleteBookByID")
    public String deleteBookByID(HttpSession session,
                             @RequestParam("id") int book_id)
    {
        Author author = (Author)session.getAttribute(SessionAttribute.AUTHOR.getName());
        if (author == null)
            return "作者未登录";
        if (!this.service_book.authorHasBook(author, book_id))
            return "书" + book_id + "与作者" + author.getId() + "无关";

        if (this.service_book.deleteBookByID(book_id) == ServiceResult.FAILED)
            return "删除失败";
        return "删除成功";
    }


    @ResponseBody
    @PostMapping("/deleteBookByName")
    public String deleteBookByName(HttpSession session,
                                 @RequestParam("name") String name)
    {
        Author author = (Author)session.getAttribute(SessionAttribute.AUTHOR.getName());
        if (author == null)
            return "作者未登录";
        if (!this.service_book.authorHasBook(author, name))
            return "书 " + name + "与作者" + author.getId() + "无关";

        if (this.service_book.deleteBookByName(name) == ServiceResult.FAILED)
            return "删除失败";
        return "删除成功";
    }



    /*Chapter*/
    @ResponseBody
    @RequestMapping("/getChapterByID")
    public Chapter getChapterByID(@RequestParam("id") int chapter_id)
    {
        return this.service_book.getChapterByID(chapter_id);
    }

    @ResponseBody
    @RequestMapping("/getChapterContentByID")
    public String getChapterContentByID(@RequestParam("id") int chapter_id)
    {
        return this.getChapterByID(chapter_id).getChapterContent();
    }

    @ResponseBody
    @RequestMapping("/getChapterInformationByID")
    public String getChapterInformationByID(@RequestParam("id") int chapter_id)
    {
        Chapter chapter = this.service_book.getChapterByID(chapter_id);
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode node = mapper.createObjectNode();
        node.put(Chapter.Column.ID.getName(), chapter.getId());
        node.put(Chapter.Column.BOOK_ID.getName(), chapter.getBookId());
        node.put(Chapter.Column.TITLE.getName(), chapter.getTitle());
        return node.toString();
    }




    @ResponseBody
    @PostMapping("/uploadChapter")
    public String uploadChapter(HttpSession session,
                                @RequestParam(value = "id") int book_id,
                                @RequestParam String title,
                                @RequestParam String content)
    {
        Author author = (Author)session.getAttribute(SessionAttribute.AUTHOR.getName());
        if (author == null)
            return "作者未登录";
        if (!this.service_book.authorHasBook(author, book_id))
            return "书" + book_id + "与作者" + author.getId() + "无关";

        if (content == null)
            return "内容为空";

        ServiceResult result = this.service_book.uploadChapter(book_id, title, content);
        return switch (result)
        {
            case SUCCESS -> "上传成功";
            case NULL -> "标题为空";
            default -> "上传失败";
        };
    }


    @ResponseBody
    @PostMapping("/deleteChapter")
    public String deleteChapter(HttpSession session,
                                @RequestParam(value = "book_id") int book_id,
                                @RequestParam(value = "chapter_id") int chapter_id)
    {
        Author author = (Author)session.getAttribute(SessionAttribute.AUTHOR.getName());
        if (author == null)
            return "作者未登录";

        Book book = this.getBookByID(book_id);
        Chapter chapter = this.getChapterByID(chapter_id);

        if (book == null)
            return "书" + book_id + "不存在";
        if (!book.getAuthorId().equals(author.getId()))
            return "书" + book_id + "与作者" + author.getId() + "无关";
        if (!chapter.getBookId().equals(book.getId()))
            return "书" + book_id + "不存在章节" + chapter_id;

        if (this.service_book.deleteChapter(chapter_id) == ServiceResult.FAILED)
            return "删除失败";
        return "删除成功";
    }


    @ResponseBody
    @PostMapping("/updateChapterTitle")
    public String updateChapterTitle(HttpSession session,
                                @RequestParam(value = "book_id") int book_id,
                                @RequestParam(value = "chapter_id") int chapter_id,
                                @RequestParam String title)
    {
        Author author = (Author)session.getAttribute(SessionAttribute.AUTHOR.getName());
        if (author == null)
            return "作者未登录";

        Book book = this.getBookByID(book_id);
        Chapter chapter = this.getChapterByID(chapter_id);

        if (book == null)
            return "书" + book_id + "不存在";
        if (!book.getAuthorId().equals(author.getId()))
            return "书" + book_id + "与作者" + author.getId() + "无关";
        if (!chapter.getBookId().equals(book.getId()))
            return "书" + book_id + "不存在章节" + chapter_id;


        if (this.service_book.updateChapterTitle(chapter_id, title) == ServiceResult.FAILED)
            return "更新失败";
        return "更新成功";
    }


    @ResponseBody
    @PostMapping("/updateChapterContent")
    public String updateChapterContent(HttpSession session,
                                @RequestParam(value = "book_id") int book_id,
                                @RequestParam(value = "chapter_id") int chapter_id,
                                @RequestParam String content)
    {
        Author author = (Author)session.getAttribute(SessionAttribute.AUTHOR.getName());
        if (author == null)
            return "作者未登录";

        Book book = this.getBookByID(book_id);
        Chapter chapter = this.getChapterByID(chapter_id);

        if (book == null)
            return "书" + book_id + "不存在";
        if (!book.getAuthorId().equals(author.getId()))
            return "书" + book_id + "与作者" + author.getId() + "无关";
        if (!chapter.getBookId().equals(book.getId()))
            return "书" + book_id + "不存在章节" + chapter_id;

        if (this.service_book.updateChapterContent(chapter_id, content) == ServiceResult.FAILED)
            return "更新失败";
        return "更新成功";
    }


    @ResponseBody
    @PostMapping("/updateChapter")
    public String updateChapter(HttpSession session,
                                       @RequestParam(value = "book_id") int book_id,
                                       @RequestParam(value = "chapter_id") int chapter_id,
                                       @RequestParam String title,
                                       @RequestParam String content)
    {
        Author author = (Author)session.getAttribute(SessionAttribute.AUTHOR.getName());
        if (author == null)
            return "作者未登录";

        Book book = this.getBookByID(book_id);
        Chapter chapter = this.getChapterByID(chapter_id);

        if (book == null)
            return "书" + book_id + "不存在";
        if (!book.getAuthorId().equals(author.getId()))
            return "书" + book_id + "与作者" + author.getId() + "无关";
        if (!chapter.getBookId().equals(book.getId()))
            return "书" + book_id + "不存在章节" + chapter_id;

        if (this.service_book.updateChapter(chapter_id, title, content) == ServiceResult.FAILED)
            return "更新失败";
        return "更新成功";
    }
}













